package thinkingInJava.generics.Mix;
// 泛型异常用法例
//generics/ThrowGenericException36.java
//TIJ4 Chapter Generics, Exercise 36, page 713
//Add a second parameterized exception to the ProcessorIntf class and 
//demonstrate that the exceptions can vary independently.
import java.util.*;

interface ProcessorIntf<T,E extends Exception, E2 extends Exception> {
	void process(List<T> resultCollector) throws E,E2;
}

class ProcessRunner2<T,E extends Exception, E2 extends Exception> 
extends ArrayList<ProcessorIntf<T,E,E2>> {
	List<T> processAll() throws E,E2 {
		List<T> resultCollector = new ArrayList<T>();
		for(ProcessorIntf<T,E,E2> processor : this)
			processor.process(resultCollector);
		return resultCollector;
	}
}

class Failure12 extends Exception {}

class Failure32 extends Exception {}

class Processor12 implements ProcessorIntf<String,Failure12,Failure32> {
	static int count = 3;
	public void
	process(List<String> resultCollector) throws Failure12, Failure32 {
		if(count-- > 1)
			resultCollector.add("Hep!");
		else
			resultCollector.add("Ho!");
		if(count < 0)
			throw new Failure12();
		if(count < -1)
			throw new Failure32();
	}
}

class Processor1b implements ProcessorIntf<String,Failure12,Failure32> {
	static int count = 3;
	public void
	process(List<String> resultCollector) throws Failure12, Failure32 {
		if(count-- > 1)
			resultCollector.add("Hep!");
		else
			resultCollector.add("Ho!");
		if(count < 0)
			throw new Failure12();
		if(count == 1)
			throw new Failure32();
	}
}

class Failure22 extends Exception {}

class Processor22 implements ProcessorIntf<Integer,Failure22,Failure32> {
	static int count = 2;
	public void
	process(List<Integer> resultCollector) throws Failure22, Failure32 {
		if(count-- == 0)
			resultCollector.add(47);
		else {
			resultCollector.add(11);
		}
		if(count < 0)
			throw new Failure22();
		if(count < -1)
			throw new Failure32();
	}
}

class Processor2b implements ProcessorIntf<Integer,Failure22,Failure32> {
	static int count = 2;
	public void
	process(List<Integer> resultCollector) throws Failure22, Failure32 {
		if(count-- == 0)
			resultCollector.add(47);
		else {
			resultCollector.add(11);
		}
		if(count < 0)
			throw new Failure22();
		if(count == 1)
			throw new Failure32();
	}
}

public class ThrowGenericException36 {
	public static void main(String[] args) {
		ProcessRunner2<String,Failure12,Failure32> runner =
			new ProcessRunner2<String,Failure12,Failure32>();
		for(int i = 0; i < 3; i++)
			runner.add(new Processor12());
		try {
			System.out.println(runner.processAll());
		} catch(Failure12 e) {
			System.out.println(e);
		} catch(Failure32 e) {
			System.out.println(e);
		}
		ProcessRunner2<String,Failure12,Failure32> runnerb =
			new ProcessRunner2<String,Failure12,Failure32>();
		for(int i = 0; i < 3; i++)
			runnerb.add(new Processor1b());
		try {
			System.out.println(runnerb.processAll());
		} catch(Failure12 e) {
			System.out.println(e);
		} catch(Failure32 e) {
			System.out.println(e);
		}
		ProcessRunner2<Integer,Failure22,Failure32> runner2 =
			new ProcessRunner2<Integer,Failure22,Failure32>();
		for(int i = 0; i < 3; i++)
			runner2.add(new Processor22());
		try {
			System.out.println(runner2.processAll());
		} catch(Failure22 e) {
			System.out.println(e);
		} catch(Failure32 e) {
			System.out.println(e);
		}
		ProcessRunner2<Integer,Failure22,Failure32> runner2b =
			new ProcessRunner2<Integer,Failure22,Failure32>();
		for(int i = 0; i < 3; i++)
			runner2b.add(new Processor2b());
		try {
			System.out.println(runner2b.processAll());
		} catch(Failure22 e) {
			System.out.println(e);
		} catch(Failure32 e) {
			System.out.println(e);
		}
	}
	
}	